/*******************************************************************************
 * Copyright (c) 2011 Gijs de Vries aka Janoz.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     Gijs de Vries aka Janoz - initial API and implementation
 ******************************************************************************/
/* COPYRIGHT (C) 2008 Gijs de Vries. All Rights Reserved. */
package com.janoz.httpd.impl;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

import com.janoz.httpd.MimeType;
import com.janoz.httpd.RequestHandler;
import com.janoz.httpd.Response;
import com.janoz.httpd.StatusCode;

/**
 * An implementation of the request handler to serve a file
 * directory tree from a arbitrary root. 
 * 
 * @author Gijs de Vries
 *
 */
public class FileHandler implements RequestHandler {

	private static final int BUFF_SIZE = 1024;
	private File rootDir;
	
	
	/**
	 * @see com.janoz.httpd.RequestHandler#handleRequest(String, Properties)
	 * @param uri the uri of the request
	 * @param params the get parameters of the request
	 * @return The generated response that will be sent to the client
	 */
	public Response handleRequest(String uri, Properties params) {
		File result = new File(rootDir.getPath() + File.separatorChar + uri);
		try {
			if (isReadableFile(result)) {
				return 	new Response(readFile(result), 
						MimeType.getMimeType(extractExtention(result)));
			} else {
				return new Response(StatusCode.NOTFOUND);
			} 
		} catch (IOException e) {
			System.err.println("Error reading file " 
					+ result.getAbsolutePath());
			return Response.createEncodingSave(StatusCode.INTERNALERROR);
		}
	}

	private String extractExtention(File result) {
		int ext = result.getName().lastIndexOf('.');
		String extension = null;
		if (ext > 0) {
			extension = result.getName().substring(ext + 1);
		}
		return extension;
	}

	private boolean isReadableFile(File result) {
		return result.exists() && !result.isDirectory() && result.canRead();
	}
	
	/**
	 * 
	 * @param rootDir The rootdir from which the files will be served.
	 */
	public void setRootDir(File rootDir) {
		this.rootDir = rootDir;
	}
	
	private byte[] readFile(File file) throws IOException {
		InputStream input = null;
		try {
			input = new FileInputStream(file);
			ByteArrayOutputStream result = new ByteArrayOutputStream();
			
	        byte[] buffer = new byte[BUFF_SIZE];
	        int n;
	        while (-1 != (n = input.read(buffer))) {
	            result.write(buffer, 0, n);
	        }
	        return result.toByteArray();
		} finally {
			if (input != null) {
				input.close();
			}
		}
	}

}
